package pprz.components;

import java.awt.Color;
import java.awt.Component;
import java.awt.Container;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.FontMetrics;
import java.awt.GradientPaint;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.GraphicsEnvironment;
import java.awt.RenderingHints;
import java.awt.Shape;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.AdjustmentEvent;
import java.awt.event.AdjustmentListener;
import java.awt.event.ComponentEvent;
import java.awt.event.ComponentListener;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.geom.AffineTransform;
import java.awt.geom.RoundRectangle2D;
import java.awt.image.BufferedImage;
import java.io.File;
import java.util.HashMap;
import java.util.Vector;

import javax.swing.BoxLayout;
import javax.swing.JCheckBoxMenuItem;
import javax.swing.JMenu;
import javax.swing.JPopupMenu;
import javax.swing.JScrollBar;
import javax.swing.event.EventListenerList;
import javax.swing.event.PopupMenuEvent;
import javax.swing.event.PopupMenuListener;
import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;

import pprz.data_components.Aircraft;
import pprz.data_components.Message;
import pprz.data_components.events.AcSelectEvent;
import pprz.data_components.events.AcSelectEventListener;
import pprz.data_components.events.DownlinkMessageEvent;
import pprz.data_components.events.DownlinkMessageEventListener;
import pprz.data_components.parsers.FlightPlanParser;

public class AcInfoContainer extends Container 
implements 	DownlinkMessageEventListener, AcSelectEventListener,
			MouseListener, ComponentListener, 
			AdjustmentListener {

	
	protected static final long serialVersionUID = 1L;
	protected static final RoundRectangle2D.Float mask=new RoundRectangle2D.Float(0,0,40,40,6,6);
	protected static final RoundRectangle2D.Float mask_long=new RoundRectangle2D.Float(0,0,82,40,6,6);
	protected static final Color green=new Color(0.6f,1.0f,0.6f);
	protected static final Color red=new Color(1.0f,0.6f,0.6f);

	
	protected InnerPanel panel;
	protected JScrollBar scroller;
	protected HashMap<Integer,AcInfo> hash;
	protected Vector<AcInfo> vect;
	protected int selected;
	protected ActionEvent e;
	protected EventListenerList listenerList = new EventListenerList();  
	protected EventListenerList acSelectListenerList = new EventListenerList();
	protected AcSelectEvent ace;	
	
	
	public static final int colors[]={0x111111, 0x111188, 0x1111FF, 0x118811,
		0x11FF11, 0x881111, 0xFF1111, 0xFF1188,
		0x881188, 0x8811FF, 0xFF11FF, 0x118888,
		0x11FFFF, 0x1188FF, 0x11FF88};

	class InnerPanel extends Container {
		
		static final long serialVersionUID=1;
	}
	
	class AcInfo extends Indicator  
	implements ActionListener, MouseListener, PopupMenuListener {

		protected static final long serialVersionUID = 2L;
	

		protected Aircraft ac;
		
		public int acid;
		
		//protected Image dbImage;  //  @jve:decl-index=0:
		protected boolean selected;

		protected int textWidth;
		protected int numbersWidth;
		protected int lineHeight;
		protected int marginX, marginY;
		
		protected Color c1,c2;
		protected BufferedImage imBAT;
		protected BufferedImage imLNK;
		protected BufferedImage imGPS;
		protected BufferedImage imAP;
		protected BufferedImage imALT;
		protected BufferedImage imCLIMB;
		protected BufferedImage imTHR;
		protected BufferedImage imDIST;
		
		protected String sID;
		protected String sName;
		protected String sAlt;
		protected String sCmdAlt;
		protected String sClimb;
		protected String sCmdClimb;
		protected String sVel;
		protected String sBat;
		protected String sThr;
		protected String sCmdThr;
		protected String sDist2Home;
		protected String sMaxDist2Home;
		protected String sDist2Wp;
		protected String sPitch;
		protected String sRoll;
		protected String sAP;
		protected String sGps;
		protected String sLnk;
		
		protected JPopupMenu menu;  //  @jve:decl-index=0:
	
		public AcInfo(Aircraft ac) {
			super();
			assert ac==null; 
			this.ac=ac;
			this.acid=ac.get_id();
			
			textWidth=33; numbersWidth=40;
			lineHeight=15;
			marginX=6; marginY=2;
			selected=false;
			
			c1 = new Color(
					(ac.get_color()>>16)&0xFF-0x33,
					(ac.get_color()>>8)&0xFF-0x33,
				(ac.get_color()>>32)&0xFF-0x33
			);
			
			c2=new Color(
				(c1.getRed()+0x80)>0xFF?0xFF:c1.getRed()+0x80,
				(c1.getGreen()+0x80)>0xFF?0xFF:c1.getGreen()+0x80,
				(c1.getBlue()+0x80)>0xFF?0xFF:c1.getBlue()+0x80
			);
			
			if (c1==null) System.out.println(ac.get_color());

			GraphicsEnvironment ge = GraphicsEnvironment.
            getLocalGraphicsEnvironment();

			BufferedImage dbImage = new BufferedImage(1,1,BufferedImage.TYPE_INT_ARGB); 
			Graphics2D g=ge.createGraphics(dbImage);
			FontMetrics f=g.getFontMetrics();
			textWidth=(int)f.getStringBounds("Pitch:  ", g).getWidth();
			lineHeight=(int)f.getStringBounds("Pitch:  ", g).getHeight();
			numbersWidth=(int)f.getStringBounds("0000.0000", g).getWidth();
			
			g.dispose();
			
			setSize(180, 155);
			setPreferredSize(this.getSize());
			setMinimumSize(this.getSize());
			setMaximumSize(new Dimension(Integer.MAX_VALUE,this.getHeight()));
			
			sID=new String("0.00");
			sName=new String("0.00");
			sAlt=new String("0.00");
			sCmdAlt=new String("0.00");
			sClimb=new String("0.00");
			sCmdClimb=new String("0.00");
			sVel=new String("0.00");
			sBat=new String("0.00");
			sThr=new String("0.00");
			sCmdThr=new String("0.00");
			sDist2Home=new String("0.00");
			sDist2Wp=new String("0.00");
			sPitch=new String("0.00");
			sRoll=new String("0.00");
			sAP=new String("man");
			sGps=new String("nofix");
			sLnk="--";
			
			
			
			imBAT=new BufferedImage((int)mask.width,(int)mask.height,BufferedImage.TYPE_3BYTE_BGR);
			
			g=imBAT.createGraphics(); 
			g.setColor(green); 
			g.fillRect(0, 0, imBAT.getWidth(), imBAT.getHeight());
			g.dispose();
			imLNK=new BufferedImage((int)mask.width,(int)mask.height,BufferedImage.TYPE_3BYTE_BGR);
			g=imLNK.createGraphics(); g.setColor(green); g.fillRect(0, 0, imLNK.getWidth(), imLNK.getHeight());
			g.dispose();
			imGPS=new BufferedImage((int)mask.width,(int)mask.height,BufferedImage.TYPE_3BYTE_BGR);
			g=imGPS.createGraphics(); g.setColor(green); g.fillRect(0, 0, imGPS.getWidth(), imGPS.getHeight());
			g.dispose();
			imAP=new BufferedImage((int)mask.width,(int)mask.height,BufferedImage.TYPE_3BYTE_BGR);
			g=imAP.createGraphics(); g.setColor(green); g.fillRect(0, 0, imAP.getWidth(), imAP.getHeight());
			g.dispose();
			imALT=new BufferedImage((int)mask_long.width,(int)mask_long.height,BufferedImage.TYPE_3BYTE_BGR);
			g=imALT.createGraphics(); g.setColor(green); g.fillRect(0, 0, imALT.getWidth(), imALT.getHeight());
			g.dispose();
			imCLIMB=new BufferedImage((int)mask_long.width,(int)mask_long.height,BufferedImage.TYPE_3BYTE_BGR);
			g=imCLIMB.createGraphics(); g.setColor(green); g.fillRect(0, 0, imCLIMB.getWidth(), imCLIMB.getHeight());
			g.dispose();
			imTHR=new BufferedImage((int)mask_long.width,(int)mask_long.height,BufferedImage.TYPE_3BYTE_BGR);
			g=imTHR.createGraphics(); g.setColor(green); g.fillRect(0, 0, imTHR.getWidth(), imTHR.getHeight());
			g.dispose();
			imDIST=new BufferedImage((int)mask_long.width,(int)mask_long.height,BufferedImage.TYPE_3BYTE_BGR);
			g=imDIST.createGraphics(); g.setColor(green); g.fillRect(0, 0, imDIST.getWidth(), imDIST.getHeight());
			g.dispose();
			
			menu=new JPopupMenu();
			JMenu m1=new JMenu("Go to block...");
			String filename=ac.get_flight_plan();
			SAXParserFactory factory = SAXParserFactory.newInstance();
			FlightPlanParser handler = new FlightPlanParser();
			try {
				// Parse the input
				SAXParser saxParser = factory.newSAXParser();
				saxParser.parse(new File(filename), handler);
				System.out.print(handler.get_blockList());
			} catch (Exception e) {
				System.err.println("File Read Error: " + filename);
				e.printStackTrace();
			}
			for (String s : handler.get_blockList())
				m1.add(s);
			
			JMenu m2=new JMenu("Actions");
			m2.add("Action 1");
			m2.add("Action 2");
			m2.add("Action 3");
			menu.add(m1);
			menu.add(new JCheckBoxMenuItem("Lock"));
			menu.add(m2);
			//this.add(menu);
			menu.addPopupMenuListener(this);
			this.addMouseListener(this);
			validate();
//			System.out.println("Called INIT!!");
			
			
		}

		public void popupMenuCanceled(PopupMenuEvent arg0) {
			// TODO Auto-generated method stub
			
		}


		public void popupMenuWillBecomeInvisible(PopupMenuEvent arg0) {
			// TODO Auto-generated method stub
			
		}


		public void popupMenuWillBecomeVisible(PopupMenuEvent arg0) {
			// TODO Auto-generated method stub
			
		}


		public void actionPerformed(ActionEvent arg0) {
			// TODO Auto-generated method stub
			
		}
	
		
		@Override
		protected void draw(Graphics g) {

			Graphics2D g2=(Graphics2D)g;
		    g2.setRenderingHint (RenderingHints.KEY_ANTIALIASING,RenderingHints.VALUE_ANTIALIAS_ON);
		    
			GradientPaint gradient=new GradientPaint(0,0,c1,this.getWidth(),0, c2);
			g2.setPaint(gradient);
			g2.fillRect(0, 0, this.getWidth(), lineHeight+4);
			g2.setColor(Color.white);
			Font f1=g2.getFont();
			Font f2=f1.deriveFont(Font.BOLD);
			g2.setFont(f2);
			g2.drawString(ac.get_name(), 2, lineHeight-2);
			
			g2.setColor(Color.black);
			g2.setFont(f1);

			int line1=lineHeight+8+g2.getFontMetrics().getHeight();
			int line2=lineHeight+8+(int)mask.getWidth()+2+g2.getFontMetrics().getHeight();
			int line3=lineHeight+8+((int)mask.getWidth()+2)*2+g2.getFontMetrics().getHeight();

			g2.draw(AffineTransform.getTranslateInstance(2,lineHeight+8).createTransformedShape(mask));
			g2.drawString("bat",((int)mask.getWidth()-g2.getFontMetrics().stringWidth("bat"))/2+2,line1);
			g2.draw(AffineTransform.getTranslateInstance(44,lineHeight+8).createTransformedShape(mask));
			g2.drawString("lnk",((int)mask.getWidth()-g2.getFontMetrics().stringWidth("lnk"))/2+44,line1);
			g2.draw(AffineTransform.getTranslateInstance(86,lineHeight+8).createTransformedShape(mask));
			g2.drawString("gps",((int)mask.getWidth()-g2.getFontMetrics().stringWidth("gps"))/2+86,lineHeight+8+g2.getFontMetrics().getHeight());
			g2.draw(AffineTransform.getTranslateInstance(128,lineHeight+8).createTransformedShape(mask));
			g2.drawString("ap",((int)mask.getWidth()-g2.getFontMetrics().stringWidth("ap"))/2+128,lineHeight+8+g2.getFontMetrics().getHeight());
			g2.draw(AffineTransform.getTranslateInstance(2,lineHeight+8+(int)mask.getWidth()+2).createTransformedShape(mask_long));
			g2.drawString("alt",((int)mask_long.getWidth()-g2.getFontMetrics().stringWidth("alt"))/2+2,line2);
			g2.draw(AffineTransform.getTranslateInstance(4+(int)mask_long.getWidth(),lineHeight+8+42).createTransformedShape(mask_long));
			g2.drawString("climb",((int)mask_long.getWidth()-g2.getFontMetrics().stringWidth("climb"))/2+2+(int)mask_long.getWidth(),lineHeight+8+42+g2.getFontMetrics().getHeight());
			g2.draw(AffineTransform.getTranslateInstance(2,lineHeight+8+((int)mask.getWidth()+2)*2).createTransformedShape(mask_long));
			g2.drawString("thr",((int)mask_long.getWidth()-g2.getFontMetrics().stringWidth("thr"))/2+2,line3);
			g2.draw(AffineTransform.getTranslateInstance(4+(int)mask_long.getWidth(),lineHeight+8+((int)mask.getWidth()+2)*2).createTransformedShape(mask_long));
			g2.drawString("dist2home",((int)mask_long.getWidth()-g2.getFontMetrics().stringWidth("dist2home"))/2+2+(int)mask_long.getWidth(),line3);
			
			
			
			
			
			
		}

		public void paint(Graphics g) {
			if (selected) g.setColor(c2);
			else g.setColor(this.getBackground());
			g.fillRect(0, 0, this.getWidth(), this.getHeight());
			drawButtons(g);
			super.paint(g);
		}		




		public void drawButtons(Graphics g)
		{
			if (ac==null) 
			{
				System.out.println("ac==null");
				return;
			}
			Graphics2D g2=(Graphics2D)g;
//			sID=String.format("%1$ 3d", ac.get_id());
//			sName=ac.get_name();
			g2.setColor(this.getForeground());
			Font f=g2.getFont();
			g2.setFont(f.deriveFont(Font.BOLD));
			Shape s=g2.getClip();
			g2.clip(AffineTransform.getTranslateInstance(2,lineHeight+8).createTransformedShape(mask));
			g2.drawImage(imBAT, 2, lineHeight+8, null);
			g2.drawString(sBat,2+(imBAT.getWidth()-g2.getFontMetrics().stringWidth(sBat))/2,(lineHeight+4)*3);
			g2.setClip(s); g2.clip(AffineTransform.getTranslateInstance(44,lineHeight+8).createTransformedShape(mask));
			g2.drawImage(imLNK, 44, lineHeight+8, null);
			g2.drawString(sLnk,44+(imLNK.getWidth()-g2.getFontMetrics().stringWidth(sLnk))/2,(lineHeight+4)*3);
			g2.setClip(s); g2.clip(AffineTransform.getTranslateInstance(86,lineHeight+8).createTransformedShape(mask));
			g2.drawImage(imGPS, 86, lineHeight+8, null);
			g2.drawString(sGps,86+(imGPS.getWidth()-g2.getFontMetrics().stringWidth(sGps))/2,(lineHeight+4)*3);
			g2.setClip(s); g2.clip(AffineTransform.getTranslateInstance(128,lineHeight+8).createTransformedShape(mask));
			g2.drawImage(imAP, 128, lineHeight+8, null);
			g2.drawString(sAP,128+(imAP.getWidth()-g2.getFontMetrics().stringWidth(sAP))/2,(lineHeight+4)*3);
			g2.setClip(s); g2.clip(AffineTransform.getTranslateInstance(2,lineHeight+8+42).createTransformedShape(mask_long));
			g2.drawImage(imALT, 2, lineHeight+8+42, null);
			g2.drawString(sAlt+"/"+sCmdAlt,2+(imALT.getWidth()-g2.getFontMetrics().stringWidth(sAlt+"/"+sCmdAlt))/2,(lineHeight+4)*3+42);
			g2.setClip(s); g2.clip(AffineTransform.getTranslateInstance(4+(int)mask_long.getWidth(),lineHeight+8+2+(int)mask.getHeight()).createTransformedShape(mask_long));
			g2.drawImage(imCLIMB, 4+(int)mask_long.getWidth(), lineHeight+8+2+(int)mask_long.getHeight(), null);
			g2.drawString(sClimb+"/"+sCmdClimb,2+(imCLIMB.getWidth()-g2.getFontMetrics().stringWidth(sClimb+"/"+sCmdClimb))/2+2+(int)mask_long.getWidth(),(lineHeight+4)*3+42);
			g2.setClip(s); g2.clip(AffineTransform.getTranslateInstance(2,lineHeight+8+(2+(int)mask.getHeight())*2).createTransformedShape(mask_long));
			g2.drawImage(imTHR, 2, lineHeight+8+2*((int)mask.getHeight()+2), null);
			g2.drawString(sThr,2+(imTHR.getWidth()-g2.getFontMetrics().stringWidth(sThr))/2,(lineHeight+4)*3+((int)mask.getHeight()+2)*2);
			g2.setClip(s); g2.clip(AffineTransform.getTranslateInstance(4+(int)mask_long.getWidth(),lineHeight+8+(2+(int)mask.getHeight())*2).createTransformedShape(mask_long));
			g2.drawImage(imDIST, 4+(int)mask_long.getWidth(), lineHeight+8+2*((int)mask.getHeight()+2), null);
			g2.drawString(sDist2Home+"/"+sDist2Home,4+(int)mask_long.getWidth()+(imDIST.getWidth()-g2.getFontMetrics().stringWidth(sDist2Home+"/"+sDist2Home))/2,(lineHeight+4)*3+((int)mask.getHeight()+2)*2);
			g2.setClip(s); 
 

 
 
			g2.setFont(f);

//			sPitch=String.format("%1$ 8.4f", ac.get_pitch());
//			sRoll=String.format("%1$ 8.4f", ac.get_roll());
			g2.setColor(Color.white);
//			g2.setFont(f.deriveFont(Font.BOLD)); g2.drawString(sName,marginX,15);
//			g.setFont(f);
			int curY=2*lineHeight;
			g2.setColor(this.getForeground());
//			g2.drawString("ID:",marginX,curY); g2.drawString(String.valueOf(ac.get_id()),marginX+textWidth,curY); curY+=lineHeight;
//			g2.drawString("Alt:",marginX,curY); 
//			g2.drawString(sAlt,marginX+textWidth,curY); curY+=lineHeight;
//			g2.drawString("Vel:",marginX,curY); 
//			g2.drawString(sVel,marginX+textWidth,curY); curY+=lineHeight;
//			g2.drawString("Pitch:",marginX,curY); 
//			g2.drawString(sPitch,marginX+textWidth,curY); curY+=lineHeight;
//			g2.drawString("Roll:",marginX,curY); 
//			g2.drawString(sRoll,marginX+textWidth,curY); curY+=lineHeight;
//			this.setPreferredSize(new Dimension(marginX+textWidth,curY));
//			this.setMinimumSize(new Dimension(marginX+textWidth,curY));
//			this.setMaximumSize(new Dimension(Integer.MAX_VALUE,curY));
		}
		
		public void select() {selected=true; repaint(100); }
		
		public void deselect() {selected=false; repaint(100); }
		
		public boolean selected() {return selected;}

		@Override
		public Dimension getMaximumSize() {
			//setMaximumSize(new Dimension(1000,size_y));
			return super.getMaximumSize();
		}

		@Override
		public Dimension getMinimumSize() {
			//setMinimumSize(new Dimension(size_x,size_y));
			return super.getMinimumSize();
		}

		@Override
		public Dimension getPreferredSize() {
			//setPreferredSize(new Dimension(this.getParent().getWidth(),size_y));
			return super.getPreferredSize();
		}

		@Override
		public int getHeight() {
		//	if (this.getParent()!=null)
		//		this.setSize(this.getParent().getWidth(), size_y);
			return super.getHeight();
		}

		public float getAlignmentY()
		{
			return Component.TOP_ALIGNMENT;
		}

		@Override
		public void messageEvent(DownlinkMessageEvent ev) {
			switch (ev.getMessage().id())
			{
			case 8: //GPS
				updateGPS();
				updateALT();
				updateCLIMB();
				break;
			case 10: //NAVIAGATION
				updateNAV();
				updateDIST();
				break;
			case 11: //PPRZ_MODE
				updatePPRZ_MODE();
				break;
			case 12: //BAT
				updateBAT();
				updateTHR();
				break;
			case 103: //FBW_STATUS
				updateFBW_STATUS();
				break;
			}
		}
		
		protected void updateGPS()
		{
			
			switch (ac.get_ap_mode()) {
			case 0: sAP="man"; break;
			case 1: sAP="auto1"; break;
			case 2: sAP="auto2"; break;
			case 3: sAP="home"; break;
			case 4: sAP="nogps"; break;
			case 5: sAP="failsafe"; break;
			default: sAP="unknown"; break;
			}
			sGps=ac.get_gps_mode()<2?"nofix":ac.get_gps_mode()>2?"3D":"2D";
			sVel=String.format("%1$ 8.4f", ac.get_gps_vel());

			Graphics2D g=(Graphics2D)imGPS.getGraphics();
			g.setColor(ac.get_gps_mode()==3?green:ac.get_gps_mode()<2?red:green);
			g.fillRect(0, 0, imGPS.getWidth(), imGPS.getHeight());
			g.dispose();
			this.repaint(100, 86, lineHeight+8, 40, 40);
		}
		
		protected void updateNAV()
		{
		}
		protected void updatePPRZ_MODE()
		{
			Graphics2D g=(Graphics2D)imAP.getGraphics();
			g.setColor(ac.get_ap_mode()<3?green:red);
			g.fillRect(0, 0, imAP.getWidth(), imAP.getHeight());
			g.dispose();
			this.repaint(100, 128, lineHeight+8, 40, 40);			
		}
		protected void updateBAT()
		{
			sBat=String.format("%1$ 5.2f", ac.get_voltage());			
			Graphics2D g=(Graphics2D)imBAT.getGraphics();
			g.copyArea(1, 0, imBAT.getWidth()-1, imBAT.getHeight(), -1, 0);
			g.setColor(green);
			int v=imBAT.getHeight()-(int)(imBAT.getHeight()*ac.get_voltage()/12.5f);
			g.drawLine(imBAT.getWidth()-1, v, imBAT.getWidth()-1,  imBAT.getHeight()-1);
			g.setColor(red);
			g.drawLine(imBAT.getWidth()-1, 0, imBAT.getWidth()-1, v);
			g.dispose();
			this.repaint(100, 2, lineHeight+8, imBAT.getWidth(), imBAT.getHeight());
		}
		protected void updateTHR()
		{
			sThr=String.format("%1$ 5.2f", ac.get_throttle());
			//System.out.println(ac.get_throttle());
			plotImage(imTHR,ac.get_throttle());
			this.repaint(100, 2, lineHeight+8+42*2, imTHR.getWidth(), imTHR.getHeight());
			
		}
		protected void updateALT()
		{
			sAlt=String.format("%1$ 5.2f", ac.get_gps_alt()/100);
			sCmdAlt=String.format("%1$ 5.2f", ac.get_des_altitude());
//			plotImage(imALT,(ac.get_gps_alt()/100-ac.get_ground_alt())/40);
			plotImage(imALT,(ac.get_gps_alt()/100-730)/40);
			this.repaint(100, 2, lineHeight+8+42, imALT.getWidth(), imALT.getHeight());	
		}

		protected void updateCLIMB()
		{
			sClimb=String.format("%1$ 5.2f", ac.get_gps_climb());
			//System.out.println(ac.get_gps_climb());
			sCmdClimb=String.format("%1$ 5.2f", ac.get_des_climb());
			this.repaint(100, 2+imALT.getWidth()+2, lineHeight+8+42, imCLIMB.getWidth(), imCLIMB.getHeight());	
		}
		
		protected void updateDIST()
		{
			sDist2Home=String.format("%1$ 5.2f", ac.get_dist2_home()/100);
			sMaxDist2Home=String.format("%1$ 5.2f", ac.get_dist2_home());
			this.repaint(100, 2+2+imDIST.getWidth(), lineHeight+8+42, imDIST.getWidth(), imDIST.getHeight());	
		}

		protected void updateFBW_STATUS()
		{
			
		}
	// make sliding plot animation on the indicators	
		protected void plotImage(BufferedImage im, float val)
		{
			Graphics2D g=(Graphics2D)im.getGraphics();
			g.copyArea(1, 0, im.getWidth()-1, im.getHeight(), -1, 0);
			g.setColor(green);
			int v=im.getHeight()-(int)(im.getHeight()*val);
			g.drawLine(im.getWidth()-1, v, im.getWidth()-1,  im.getHeight()-1);
			g.setColor(red);
			g.drawLine(im.getWidth()-1, 0, im.getWidth()-1, v);
			g.dispose();		
		}

		public void mouseClicked(MouseEvent arg0) {
			// TODO Auto-generated method stub
			
		}

		public void mouseEntered(MouseEvent arg0) {
			// TODO Auto-generated method stub
			
		}

		public void mouseExited(MouseEvent arg0) {
			// TODO Auto-generated method stub
			
		}

		public void mousePressed(MouseEvent e) {
			if (!e.getSource().equals(this)) return;
			else if (e.getButton()==MouseEvent.BUTTON3)
			{
		        if (e.isPopupTrigger()) menu.show(e.getComponent(),e.getX(), e.getY());
			}
		}

		public void mouseReleased(MouseEvent e) {
			if (!e.getSource().equals(this)) return;
			else if (e.getButton()==MouseEvent.BUTTON3)
			{
		        if (e.isPopupTrigger()) menu.show(e.getComponent(),e.getX(), e.getY());
			}
		}
		
		
	} //end AcInfo
	
	
	
	
	public AcInfoContainer() {
		super();
		alloc();
		
		acSelectListenerList = new EventListenerList();
		this.addComponentListener(this);
		scroller.setFocusable(false);
		scroller.setMinimum(0);
		scroller.setMaximum(200);
		scroller.setUnitIncrement(1);
		scroller.addAdjustmentListener(this);
		scroller.setVisibleAmount(5);
		this.panel.setLayout(new BoxLayout(this.panel,BoxLayout.Y_AXIS));
		this.panel.addComponentListener(this);
//		panel.setVisible(false);
		this.add(panel);
		this.add(scroller);
//		this.setMinimumSize(new Dimension(30+10,10));
//		this.setMaximumSize(new Dimension(30+10,10));
		this.addAcSelectEventListener(this);
		this.setComponentZOrder(panel, 1);
		this.setComponentZOrder(scroller, 0);
	}
	
	
/*	public void paint(Graphics g)
	{
		g.setColor(getBackground());
		g.fillRect(0,0,getWidth(),getHeight());
		super.paint(g);
	}
*/	
	/**
	 * This method initializes this
	 * 
	 * @return void
	 */
	protected void alloc() {
		this.e=new ActionEvent(this,0,null);
		this.ace=new AcSelectEvent(this,0);
		this.vect=new Vector<AcInfo>();
		this.hash=new HashMap<Integer,AcInfo>();
		this.panel=new InnerPanel();
		this.scroller=new JScrollBar();
	}

	
	public int getSelected() {return selected;}
	public void mouseClicked(MouseEvent e) {}
	public void mouseEntered(MouseEvent e) {}
	public void mouseExited(MouseEvent e) {}
	public void mousePressed(MouseEvent e) {}

	public void mouseReleased(MouseEvent e) {
		Component c=e.getComponent();
		if (c.getClass()==AcInfo.class) 
		{
			if (!((AcInfo)c).selected)
			{
				ace.setAc(((AcInfo)c).acid);
				fireAcSelectEvent(this.ace);
			}
		}
	}

	public void messageEvent(DownlinkMessageEvent ev) {
		Message m = ev.getMessage();
		int msgid=m.acRec().lastMSG;
		int acid=m.acRec().get_id();
		if (msgid!=6 && msgid!=8 && msgid!=12 && msgid!=11 && msgid!=103) return; //skip it
		if (!hash.containsKey(acid)) add(m.acRec());
		else hash.get(acid).messageEvent(ev);
	}

	protected void add(Aircraft a)
	{
		if (vect.size()==0) { 
			ace.setAc(a.get_id());
			this.fireAcSelectEvent(ace);
		}
		AcInfo acpanel=new AcInfo(a);
		acpanel.setBackground(this.panel.getBackground());
		hash.put(a.get_id(), acpanel);
		vect.add(acpanel);
		acpanel.addMouseListener(this);
		this.panel.add(acpanel);
		//update sizes
		int size_y= vect.size()*(vect.get(0).getHeight()+3);
		panel.setSize(new Dimension(this.getWidth(),size_y));
		int diff=(size_y-this.getHeight());
		if (diff>0) scroller.setMaximum(diff);
	}
	
    // These methods allows classes to register for MyEvents
    public void addActionListener(ActionListener listener) {
    	listenerList.add(ActionListener.class, listener);
   }

    // This methods allows classes to unregister for MyEvents
   public void removeActionListener(ActionListener listener) {
	   listenerList.remove(ActionListener.class, listener);
   }
   
   // This protected class is used to fire MyEvents
   protected void fireActionEvent(ActionEvent evt) {
       Object[] listeners = listenerList.getListenerList();
       // Each listener occupies two elements - the first is the listener class
       // and the second is the listener instance
       for (int i=0; i<listeners.length; i+=2) {
           if (listeners[i]==ActionListener.class) {
               ((ActionListener)listeners[i+1]).actionPerformed(evt);
           }
       }
   }	
   

 		
    // These methods allows classes to register for MyEvents
    public void addAcSelectEventListener(AcSelectEventListener listener) {
        listenerList.add(AcSelectEventListener.class, listener);
    }
    // This methods allows classes to unregister for MyEvents
    public void removeAcSelectEventListener(AcSelectEventListener listener) {
        listenerList.remove(AcSelectEventListener.class, listener);
    }
  
    protected void fireAcSelectEvent(AcSelectEvent evt) {
        Object[] listeners = listenerList.getListenerList();
        // Each listener occupies two elements - the first is the listener class
        // and the second is the listener instance
        for (int i=0; i<listeners.length; i+=2) {
            if (listeners[i]==AcSelectEventListener.class) {
                ((AcSelectEventListener)listeners[i+1]).acSelectEvent(evt);
            }
        }
    }
    
	public void acSelectEvent(AcSelectEvent ev) {
		// TODO Auto-generated method stub
		AcInfo c=hash.get(ev.getAc());
		AcInfo c1=hash.get(selected);
		if (c!=null) {
			((AcInfo)c).select();
			if (c1!=null) hash.get(selected).deselect();
			selected=ev.getAc();
			System.out.println(selected);
		}
	}


	public float getAlignmentY()
	{
		return Component.BOTTOM_ALIGNMENT;
	}
   
	public void paint(Graphics g) {
		g.setColor(getBackground());
		g.fillRect(0,0,getWidth(),getHeight());
		super.paint(g);
	}


	public void componentHidden(ComponentEvent arg0) {		
	}


	public void componentMoved(ComponentEvent arg0) {
	}


	public void componentResized(ComponentEvent arg0) {
		
		if (vect.size()==0) return;
		if (arg0.getComponent().equals(this)){
			panel.setSize(this.getWidth()-scroller.getWidth(),panel.getHeight());
			System.out.println("panel height="+panel.getHeight()+" Component height="+this.getHeight());
		}
		int diff=panel.getHeight()-this.getHeight();
		if (diff>0) {
			scroller.setMaximum(diff);
			scroller.setSize(15,this.getHeight());
			scroller.setVisible(true);
		}
		else {
			scroller.setVisible(false);
			panel.setSize(this.getWidth(),panel.getHeight());			
		}
		scroller.setLocation(this.getWidth()-scroller.getWidth(), 0);
		validate();
//		this.panel.doLayout();
//		this.doLayout();
//		this.repaint(10);
	}

	

	public void componentShown(ComponentEvent arg0) {
	}


	public void adjustmentValueChanged(AdjustmentEvent arg0) {
		if (arg0.getSource()!=scroller || vect.size()==0) return;
		panel.setLocation(panel.getX(), -arg0.getValue());
		//repaint(100);
		System.out.println("scrolling");
	}   
	
	
	
} //class
